#ifndef __INTERACTIVEJUDGE_HPP__
#define __INTERACTIVEJUDGE_HPP__

#include "baseJudge.hpp"

class InteractiveJudge : public JudgeType<InteractiveJudge> {
public:
    InteractiveJudge();
    template <class Event>
    run_code_event_t next_event(Event e);
};


template <class Event>
run_code_event_t InteractiveJudge::next_event(Event e) {
    using std::is_same_v;
    const auto& context = *this->belong_context;
    if constexpr (is_same_v<Event, initial_event>) {
        if (context.get_latest_status().result != RUN_OK) {
            return end_event{};
        }
        return spj_code_compile_event{};
    }
    if constexpr (is_same_v<Event, spj_code_compile_event>) {
        if (context.get_latest_status().result != RUN_OK) {
            return end_event{};
        }
        return std_code_compile_event{};
    }
    if constexpr (is_same_v<Event, std_code_compile_event>) {
        return user_code_compile_event{};
    }
    if constexpr (is_same_v<Event, user_code_compile_event>) {
        if (context.get_latest_status().result != RUN_OK) {
            return end_event{};
        }
        return twins_spj_std_run_event{};
    }
    if constexpr (is_same_v<Event, twins_spj_std_run_event>) {
        return twins_spj_user_run_event{};
    }
    if constexpr (is_same_v<Event, twins_spj_user_run_event>) {
        return calculate_result_event{};
    }
    if constexpr (is_same_v<Event, calculate_result_event>) {
        // all test example is tested
        if (inFiles.size() == example_index) {
            return end_event{};
        // latest test is error
        } else if (context.result.passExample != context.result.testExample) {
            int ruler = context.params.ruler;
            // OI CONTENT continue test
            if (ruler == OI_CONTENT) {
            // ACM CONTENT exit
            } else if (ruler == ACM_CONTENT) {
                return end_event{};
            }
        }
        return twins_spj_std_run_event{};
    }
    return end_event{};
}



#endif /* __INTERACTIVEJUDGE_HPP__ */
